
use anyhow::Result;

use hyper::{Request, Response, Client, body};
use hyper::client::HttpConnector;
use std::collections::HashMap;

use serde::{Deserialize, Serialize};
use std::borrow::Borrow;

use std::ops::Sub;
use sqlx::{Pool, MySql, types};
use chrono;

use crate::miner::{JsonRpcResponse, JsonRpcError};
use crate::miner;
use crate::db;
use crate::miner::types::TaskType;

struct WorkerTaskCount {
    pub worker: String,
    pub running: usize,
    pub sector: Option<usize>,
    pub task: Option<usize>,
}

/// 比较正在运行的任务数量，同数据库seal_task表, sector表的记录的差异
pub async fn compare_jobs_and_database(pool: &Pool<MySql>, client: &Client<HttpConnector>, url: &str, token: &str) -> Result<()> {
    let rsp = miner::jobs::query_jobs_from_miner(client, url, token).await?;
    if let Some(e) = rsp.error {
        log::info!("receive error from miner when query workers, {:?}", e);
        return Ok(())
    }
    let workers = rsp.result.unwrap();
    if workers.is_empty(){
        println!("no worker running with miner.");
        return Ok(())
    }

    let seal_task = db::query_worker_seal_task_count(pool).await?;
    let sector_count = db::query_worker_sector_count(pool).await?;

    let mut running = HashMap::<String, WorkerTaskCount>::new();

    for (ref worker, jobs) in workers {
        let mut count = 0;
        for job in jobs {
            if job.task.eq(&TaskType::PreCommit1) {
                count = count + 1;
            }
        }
        running.insert(worker.clone(), WorkerTaskCount{
            worker: worker.clone(),
            running: count,
            sector: None,
            task: None
        });
    }

    for task in seal_task {
        let mut count = running.get_mut(&task.worker_id);
        if count.is_some(){
            let mut c = count.unwrap();
            c.task = Some(task.task_count as usize)
        }
    }

    for sector in sector_count{
        let mut count = running.get_mut(&sector.worker_id);
        if count.is_some(){
            let mut c = count.unwrap();
            c.sector = Some(sector.task_count as usize)
        }
    }

    for (w, count) in running{
        log::info!("worker {}, running {}, seal task {:?}, sector {:?}", w, count.running, count.task, count.sector);
    }

    return Ok(())
}